package org.ands.data;

import java.util.List;
import java.util.Map;

import org.ands.input.IInputHelperFactory;
import org.ands.xml.DOMHelper;
import org.ands.xml.DOMHelperCloneRoot;
import org.ands.xml.DOMHelperFromUri;
import org.w3c.dom.NodeList;


public class ContentsRetrieverOaiPmh  {
	
	public ContentsRetrieverOaiPmh(
			final String baseUri,
			final String parameterString,
			final String metadataPrefix,
			final String rootNodeName,  //MD_Metadata
			boolean fetchNext){ // Seek value of resumption token and fetch next, otherwise, just fetch for this uri
	
		String fullURI = String.format("%s?%s", baseUri, parameterString);
		if(metadataPrefix != null && !(metadataPrefix.isEmpty())){
			fullURI += String.format("&metadataPrefix=%s", metadataPrefix);
		}
		
		retrieveNodesFromURI(fullURI, rootNodeName, fetchNext);
		_baseUri = baseUri;
		_metadataPrefix = metadataPrefix;
		_rootNodeName = rootNodeName;
		_fetchNext = fetchNext;
	}
	
	/** Get the nodelist from the current uri 
	 * @throws Exception */
	private void retrieveNodesFromURI(final String uri, final String rootNodeName, final boolean fetchNext){
		
		try{
			
			_resumptionToken = null;  // Reset so that we can grab anew
			_nextNodeList = null;
			
			DOMHelperFromUri domHelper = new DOMHelperFromUri(uri);
			_nextNodeList = domHelper.getElementListFromRootNS("//*[local-name()=\'"+rootNodeName+"\']");
			
			if(!fetchNext){
				System.out.println("Retrieved "+currentNodeCount()+" nodes from "+uri+" - not seeking resumption token because 'fetchNext' is false");
				return;
			}
		
			
			NodeList resumptionTokenList = domHelper.getElementListFromRootNS("//*[local-name()=\'resumptionToken\']");
			if(resumptionTokenList.getLength() > 0){
				assert(resumptionTokenList.getLength() == 1); // One only expected
				_resumptionToken = resumptionTokenList.item(0).getTextContent();
				
			}
			
			if((_resumptionToken == null) || (_resumptionToken.isEmpty())){
				System.out.println("No resumption token retrieved at uri "+uri);
			}
			else{
				System.out.println("Resumption token "+_resumptionToken+" retrieved at uri "+uri);
			}
			
		}
		catch(Exception e){
			System.out.println("No nodes found with name "+rootNodeName+" at uri "+uri);
		}
	}
	
	NodeList _nextNodeList;
	String _baseUri;
	String _metadataPrefix;
	String _rootNodeName;
	String _resumptionToken;
	boolean _fetchNext;
	
	
	private int currentNodeCount(){
		if(_nextNodeList == null)
			return 0;
		
		return _nextNodeList.getLength();
	}
	public boolean hasNodes(){ 
		return (_nextNodeList != null);
	}
	
	public NodeList getNodes(){
		
		// Return current nodeList
		NodeList currentNodeList = _nextNodeList;
		
		if((_resumptionToken == null) || (_resumptionToken.isEmpty())){
			System.out.println("No resumption token retrieved so no more to retrieve");
			_nextNodeList = null;
		}
		else{
			retrieveNodesFromURI(String.format("%s?verb=ListRecords&resumptionToken=%s", _baseUri, _resumptionToken), _rootNodeName, _fetchNext);
		}
		
		return currentNodeList;
	}
}
